package ITU_ShuttleTracker.Admin;

/**
 *
 * @author Numan Ertugrul
 */
import java.io.IOException;
import java.io.Serializable;
import ITU_ShuttleTracker.Database;
import ITU_ShuttleTracker.User.Location.Location;
import ITU_ShuttleTracker.User.ShuttleBus.ShuttleBus;
import ITU_ShuttleTracker.User.User;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.model.map.DefaultMapModel;
import org.primefaces.model.map.LatLng;
import org.primefaces.model.map.MapModel;
import org.primefaces.model.map.Marker;

@ManagedBean(name = "MapBean")
@SessionScoped
public class MapBean implements Serializable {
    public MapModel simpleModel;
    private List<Marker> markerList;
    private List<LatLng> coordinateList;
    private List<ShuttleBus> shuttleBusList;
    private int count;
    
    private Boolean control = true;
    private int op_count = 99;
    private int half_count1 = 50;
    private int half_count2 = 49;
    
    private Location userLocation;
    private User user;
    private String information;

    public MapBean() throws IOException {
        this.userLocation = new Location("Konumunuz", 41.10377863119175, 29.024966041610696);
        this.user = new User(this.userLocation);
        this.information = "";
        
        simpleModel = new DefaultMapModel();
        simpleModel.addOverlay(new Marker(this.userLocation.getCoordinate(), "Konumunuz", "", "http://maps.google.com/mapfiles/ms/micons/blue-dot.png"));

        this.coordinateList = new ArrayList<LatLng>();
        this.shuttleBusList = new ArrayList<ShuttleBus>();
        Database database = new Database();
        try {
            database.connect();
            this.user.setRoute(database.selectRoute());
            this.coordinateList = database.selectGPS();
            this.shuttleBusList = database.selectShuttleBus();
            database.disconnect();
        } catch (Exception exception) {
            System.out.println(exception.toString());
        }
        
        this.markerList = new ArrayList<Marker>();
        LatLng coord1 = new LatLng(coordinateList.get(0).getLat(), coordinateList.get(0).getLng());
        this.markerList.add(new Marker(coord1, new Integer(this.shuttleBusList.get(0).getShuttleNo()).toString(),"", "http://maps.google.com/mapfiles/kml/pal2/icon39.png"));


        LatLng coord2 = new LatLng(coordinateList.get(49).getLat(), coordinateList.get(49).getLng());
        this.markerList.add(new Marker(coord2, new Integer(this.shuttleBusList.get(1).getShuttleNo()).toString(),"", "http://maps.google.com/mapfiles/kml/pal2/icon47.png"));

        LatLng coord3 = new LatLng(coordinateList.get(50).getLat(), coordinateList.get(50).getLng());
        this.markerList.add(new Marker(coord3, new Integer(this.shuttleBusList.get(2).getShuttleNo()).toString(),"", "http://maps.google.com/mapfiles/kml/pal4/icon7.png"));

        LatLng coord4 = new LatLng(coordinateList.get(99).getLat(), coordinateList.get(99).getLng());
        this.markerList.add(new Marker(coord4, new Integer(this.shuttleBusList.get(3).getShuttleNo()).toString(),"", "http://maps.google.com/mapfiles/kml/pal4/icon54.png"));

        for (Marker marker : this.markerList) {
            simpleModel.addOverlay(marker);
        }
    }

    public int getHalf_count1() {
        return half_count1;
    }

    public void setHalf_count1(int half_count1) {
        this.half_count1 = half_count1;
    }

    public int getHalf_count2() {
        return half_count2;
    }

    public void setHalf_count2(int half_count2) {
        this.half_count2 = half_count2;
    }

    public int getOp_count() {
        return op_count;
    }

    public void setOp_count(int op_count) {
        this.op_count = op_count;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public List<LatLng> getCoordinateList() {
        return coordinateList;
    }

    public void setCoordinateList(List<LatLng> coordinateList) {
        this.coordinateList = coordinateList;
    }

    public List<ShuttleBus> getShuttleBusList() {
        return shuttleBusList;
    }

    public void setShuttleBusList(List<ShuttleBus> shuttleBusList) {
        this.shuttleBusList = shuttleBusList;
    }

    public List<Marker> getMarkerList() {
        return markerList;
    }

    public void setMarkerList(List<Marker> markerList) {
        this.markerList = markerList;
    }
 
    /**
     * Getter method of user
     * @return User
     */
    public User getUser() {
        return user;
    }

    /**
     * Setter method of user
     * @param user User
     */
    public void setUser(User user) {
        this.user = user;
    }

    /**
     * Getter method of user location
     * @return User location
     */
    public Location getUserLocation() {
        return userLocation;
    }

    /**
     * Setter method of user location
     * @param userLocation User location 
     */
    public void setUserLocation(Location userLocation) {
        this.userLocation = userLocation;
    }
    
    /**
     * Setter information method
     * @return Information
     */
    public String getInformation() {
        //showShuttleTrackerInformation();
        return information;
    }

    /**
     * Getter information method
     * @param information Information 
     */
    public void setInformation(String information) {
        this.information = information;
    }        
            
    public void increment() {
        LatLng coord1 = new LatLng(coordinateList.get(count).getLat(), coordinateList.get(count).getLng());
        LatLng coord2 = new LatLng(coordinateList.get(op_count).getLat(), coordinateList.get(op_count).getLng());
        LatLng coord3 = new LatLng(coordinateList.get(half_count1).getLat(), coordinateList.get(half_count1).getLng());
        LatLng coord4 = new LatLng(coordinateList.get(half_count2).getLat(), coordinateList.get(half_count2).getLng());

        if (control == true) {
            this.markerList.get(0).setLatlng(coord1);
            this.markerList.get(1).setLatlng(coord2);
            this.markerList.get(2).setLatlng(coord3);
            this.markerList.get(3).setLatlng(coord4);
            
            map();

            if (count >= 49 && count != 99) {
                half_count2++;
                half_count1--;
                op_count--;
                count++;
                System.out.println("count: "+ count );
                System.out.println("half_count2: "+ half_count2);
                System.out.println("half_count1: "+ half_count1);
            } else if (count <49 && count != 99) {
                half_count2--;
                half_count1++;
                op_count--;
                count++;
                System.out.println("count: "+ count );
                System.out.println("half_count2: "+half_count2);
                System.out.println("half_count1: "+ half_count1);
            } else if (count == 99) {
                control = false;
            }
        } 
        else if (control == false) {
            this.markerList.get(0).setLatlng(coord1);
            this.markerList.get(1).setLatlng(coord2);
            this.markerList.get(2).setLatlng(coord3);
            this.markerList.get(3).setLatlng(coord4);
            
            map();

            if (count >= 51 && count != 0) {
                half_count2++;
                half_count1--;
                op_count++;
                count--;
            } else if (count < 51 && count != 0) {
                half_count2--;
                half_count1++;
                op_count++;
                count--;
            } else if (count == 0) {
                control = true;
            }
        }
    }

    public Boolean getControl() {
        return control;
    }

    public void setControl(Boolean control) {
        this.control = control;
    }

    public MapModel getSimpleModel() {
        return simpleModel;
    }
    
    public void map() {
        for (Marker marker : this.markerList) {
            simpleModel.addOverlay(marker);
        }
    }
    
    /**
     * Find the nearest station method
     */
    public void findNearestStation() {
        double shortDistance = 1000000;
        int stationID = 0;
        Location nearestStation = new Location(0, 0);
        int counter = 0;
        for (Location location : this.user.getRoute().getStationList()) {
            double distance = Math.sqrt(Math.pow(this.userLocation.getCoordinate().getLat() - location.getCoordinate().getLat(), 2) + Math.pow(this.userLocation.getCoordinate().getLng() - location.getCoordinate().getLng(), 2));
            if (shortDistance > distance) {
                nearestStation.setName(location.getName());
                nearestStation.setCoordinate(new LatLng(location.getCoordinate().getLat(), location.getCoordinate().getLng()));
                shortDistance = distance;
                stationID = counter;
            }
            counter++;
        }
        this.user.setNearestStation(this.user.getRoute().getStationList().get(stationID));
    }
    
    /**
     * Find the nearest shuttle bus
     */
    public void findNearestShuttleBus() {
        double shortDistance = 1000000;
        int shuttleBusNo = 0;
        int counter = 0;
        for (Marker shuttleBusMarker : this.markerList) {
            double distance = Math.sqrt(Math.pow(this.userLocation.getCoordinate().getLat() - shuttleBusMarker.getLatlng().getLat(), 2) + Math.pow(this.userLocation.getCoordinate().getLng() - shuttleBusMarker.getLatlng().getLng(), 2));
            if (shortDistance > distance) {
                shortDistance = distance;
                shuttleBusNo = counter;
            }
            counter++;
        }
        this.user.setNearestShuttleBus(this.shuttleBusList.get(shuttleBusNo));
    }
     
    /**
     * Show shuttle tracker information
     */
    public void showShuttleTrackerInformation() {
        findNearestStation();
        String nearestStation = this.user.getNearestStation().getName();
        findNearestShuttleBus();
        int shuttleBusNo = this.user.getNearestShuttleBus().getShuttleNo();
        String shuttleBusInformation = this.user.getNearestShuttleBus().getInformation();
        if (this.user.getNearestShuttleBus().isIsOnTheService()) {
            this.information = "En yakın durak: " + nearestStation + ", Servis No: " + shuttleBusNo + ", Servis bilgisi: " + shuttleBusInformation;
        }
        else {
            this.information = "Hizmet verilmiyor.";
        }
    }
}